// ============================== 导入依赖 ============================== //

const REG_APP = /Android|webOS|iPhone|iPad|iPod|windows|BlackBerry|opera mini|opera mobile|appleWebkit.*mobile|mobile/i

// ============================== 导出判断工具 ============================== //

export default {
  // —————————————————————————————— 判断环境 —————————————————————————————— //

  /**
   * 是否为生产环境
   *
   * @returns {Boolean} true/false
   */
  isProd: () => process.env.VUE_APP_IS_PROD,

  /**
   * 是否为移动端
   */
  isApp: () => REG_APP.test(navigator.userAgent),

  /**
   * 是否为电脑端
   */
  isWeb: () => !REG_APP.test(navigator.userAgent),

  // —————————————————————————————— 判断为空 —————————————————————————————— //

  /**
   * 是否为空 (0 不算，为 0 时需要展示) (包括 '' / false / null / undefined / isNaN / {} / [] / [[]] )
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isEmpty(data) {
    if (!data && data !== 0) return true
    if (Array.isArray(data)) {
      if (data.length === 1) return Array.isArray(data[0]) && !data[0].length
      return !data.length
    }
    if (typeof data === 'object') {
      return !Object.keys(data).length
    }
    return false
  },

  /**
   * 是否全部为空
   *
   * @param {*} data1 数据一
   * @param {*} data2 数据二
   * @param {*} datan 数据几
   *
   * @returns {Boolean} true/false
   */
  isEmptyAll(...dataList) {
    return dataList.every(this.isEmpty)
  },

  /**
   * 是否某项为空
   *
   * @param {*} data1 数据一
   * @param {*} data2 数据二
   * @param {*} datan 数据几
   *
   * @returns {Boolean} true/false
   */
  isEmptySome(...dataList) {
    return dataList.some(this.isEmpty)
  },

  // —————————————————————————————— 判断整数 —————————————————————————————— //

  /**
   * 是否为整数
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isInt: (data) => /^\d+$/.test(data),

  // —————————————————————————————— 判断基本类型 —————————————————————————————— //

  /**
   * 是否为真假
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isBoolean: (data) => typeof data === 'boolean',

  /**
   * 是否为数字
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isNumber: (data) => typeof data === 'number',

  /**
   * 是否为字符串
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isString: (data) => typeof data === 'string',

  /**
   * 是否为标识符
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isSymbol: (data) => typeof data === 'symbol',

  // —————————————————————————————— 判断复杂类型 —————————————————————————————— //

  /**
   * 是否为方法
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isFunction: (data) => typeof data === 'function',

  /**
   * 是否为类
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isClass: (data) => typeof data === 'function' && typeof data.constructor === 'function',

  /**
   * 是否为类的对象
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isClassObj: (data) => Object.prototype.toString.call(data) === '[object Object]' && getProtoName(data) !== 'Object',

  /**
   * 是否为 JSON (纯粹对象，非空，非文件，非事件，非组件，等)
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isJSON: (data) => Object.prototype.toString.call(data) === '[object Object]' && getProtoName(data) === 'Object',

  /**
   * 是否为数组
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isArray: (data) => Array.isArray(data),

  /**
   * 是否为日期
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isDate: (data) => data instanceof Date,

  /**
   * 是否为正则表达式
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isRegExp: (data) => data instanceof RegExp,

  /**
   * 是否为表单数据
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isFormData: (data) => data instanceof FormData,

  // —————————————————————————————— 判断特殊对象 —————————————————————————————— //

  /**
   * 是否为文件
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isFile: (data) => getProtoName(data) === 'File',

  /**
   * 是否为事件
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isEvent: (data) => /Event$/.test(getProtoName(data)),

  /**
   * 是否为组件
   *
   * @param {*} data 数据
   *
   * @returns {Boolean} true/false
   */
  isComponent: (data) => getProtoName(data) === 'VueComponent',
}

// ============================== 内部方法 ============================== //

/**
 * 获取原型名称
 */
// eslint-disable-next-line no-proto
const getProtoName = (data) => (data && data.__proto__ ? data.__proto__.constructor.name : '')
